#pragma once
#include "Kv_Foundation.hpp"
#include <memory>
#include <string>
#include <vector>
#include <unordered_map>
#include <optional>
#include <algorithm>

using namespace Redis_Foundation_Model;

class KvMore {
private:
    std::shared_ptr<Redis_Foundation_Model::Redis_Client> _redis;
    std::string _namespace;

    // 构建二级键
    std::string buildKey(const std::string& primary, const std::string& secondary) const {
        return _namespace + ":" + primary + ":" + secondary;
    }

    // 构建模式匹配键
    std::string buildPattern(const std::string& primary) const {
        return _namespace + ":" + primary + ":*";
    }

    // 从完整键中提取二级键
    std::string extractSecondaryKey(const std::string& fullKey) const {
        size_t lastColon = fullKey.find_last_of(':');
        if (lastColon != std::string::npos) {
            return fullKey.substr(lastColon + 1);
        }
        return fullKey;
    }

public:
    // 构造函数
    explicit KvMore(const std::string& namespace_prefix = "kvmore") 
        : _namespace(namespace_prefix) {
        _redis = Redis_Foundation_Model::Redis_Client::GetInstance();
    }

    KvMore(std::shared_ptr<Redis_Foundation_Model::Redis_Client> redis, const std::string& namespace_prefix = "kvmore")
        : _redis(redis), _namespace(namespace_prefix) {}

    // 设置命名空间
    void setNamespace(const std::string& namespace_prefix) {
        _namespace = namespace_prefix;
    }

    // 获取命名空间
    std::string getNamespace() const {
        return _namespace;
    }

    // 基础操作
    template<typename T>
    bool set(const std::string& primary, const std::string& secondary, const T& value) {
        std::string key = buildKey(primary, secondary);
        return _redis->set(key, value);
    }

    template<typename T>
    bool setnx(const std::string& primary, const std::string& secondary, const T& value) {
        std::string key = buildKey(primary, secondary);
        return _redis->setnx(key, value);
    }

    template<typename T>
    bool setex(const std::string& primary, const std::string& secondary, int seconds, const T& value) {
        std::string key = buildKey(primary, secondary);
        return _redis->setex(key, seconds, value);
    }

    template<typename T>
    std::optional<T> get(const std::string& primary, const std::string& secondary) {
        std::string key = buildKey(primary, secondary);
        return _redis->get<T>(key);
    }

    bool exists(const std::string& primary, const std::string& secondary) {
        std::string key = buildKey(primary, secondary);
        return _redis->exists(key);
    }

    bool del(const std::string& primary, const std::string& secondary) {
        std::string key = buildKey(primary, secondary);
        return _redis->del(key);
    }

    bool expire(const std::string& primary, const std::string& secondary, int seconds) {
        std::string key = buildKey(primary, secondary);
        return _redis->expire(key, seconds);
    }

    long long ttl(const std::string& primary, const std::string& secondary) {
        std::string key = buildKey(primary, secondary);
        return _redis->ttl(key);
    }

    // 列表操作
    template<typename T>
    bool lpush(const std::string& primary, const std::string& secondary, const T& value) {
        std::string key = buildKey(primary, secondary);
        return _redis->lpush(key, value);
    }

    template<typename T>
    bool rpush(const std::string& primary, const std::string& secondary, const T& value) {
        std::string key = buildKey(primary, secondary);
        return _redis->rpush(key, value);
    }

    template<typename T>
    std::optional<T> lpop(const std::string& primary, const std::string& secondary) {
        std::string key = buildKey(primary, secondary);
        return _redis->lpop<T>(key);
    }

    template<typename T>
    std::optional<T> rpop(const std::string& primary, const std::string& secondary) {
        std::string key = buildKey(primary, secondary);
        return _redis->rpop<T>(key);
    }

    template<typename T>
    std::vector<T> lrange(const std::string& primary, const std::string& secondary, 
                         long long start, long long stop) {
        std::string key = buildKey(primary, secondary);
        return _redis->lrange<T>(key, start, stop);
    }

    long long llen(const std::string& primary, const std::string& secondary) {
        std::string key = buildKey(primary, secondary);
        try {
            auto items = _redis->lrange<std::string>(key, 0, -1);
            return static_cast<long long>(items.size());
        } catch (...) {
            return 0;
        }
    }

    // 哈希操作
    template<typename Field, typename Value>
    bool hset(const std::string& primary, const std::string& secondary, 
              const Field& field, const Value& value) {
        std::string key = buildKey(primary, secondary);
        return _redis->hset(key, field, value);
    }

    template<typename Field, typename Value>
    bool hset(const std::string& primary, const std::string& secondary,
              const std::unordered_map<Field, Value>& fieldValues) {
        std::string key = buildKey(primary, secondary);
        return _redis->hset(key, fieldValues);
    }

    template<typename T>
    std::optional<T> hget(const std::string& primary, const std::string& secondary, 
                         const std::string& field) {
        std::string key = buildKey(primary, secondary);
        return _redis->hget<T>(key, field);
    }

    template<typename Value>
    std::unordered_map<std::string, Value> hgetall(const std::string& primary, 
                                                  const std::string& secondary) {
        std::string key = buildKey(primary, secondary);
        return _redis->hgetall<Value>(key);
    }

    template<typename Field>
    bool hdel(const std::string& primary, const std::string& secondary, const Field& field) {
        std::string key = buildKey(primary, secondary);
        return _redis->hdel(key, field);
    }

    template<typename Field>
    bool hexists(const std::string& primary, const std::string& secondary, const Field& field) {
        std::string key = buildKey(primary, secondary);
        return _redis->hexists(key, field);
    }

    // 集合操作
    template<typename T>
    bool sadd(const std::string& primary, const std::string& secondary, const T& member) {
        std::string key = buildKey(primary, secondary);
        return _redis->sadd(key, member);
    }

    template<typename T>
    bool srem(const std::string& primary, const std::string& secondary, const T& member) {
        std::string key = buildKey(primary, secondary);
        return _redis->srem(key, member);
    }

    template<typename T>
    bool sismember(const std::string& primary, const std::string& secondary, const T& member) {
        std::string key = buildKey(primary, secondary);
        return _redis->sismember(key, member);
    }

    template<typename T>
    std::vector<T> smembers(const std::string& primary, const std::string& secondary) {
        std::string key = buildKey(primary, secondary);
        return _redis->smembers<T>(key);
    }

    // 计数器操作
    long long incr(const std::string& primary, const std::string& secondary, long long increment = 1) {
        std::string key = buildKey(primary, secondary);
        return _redis->incr(key, increment);
    }

    double incrbyfloat(const std::string& primary, const std::string& secondary, double increment = 1.0) {
        std::string key = buildKey(primary, secondary);
        return _redis->incrbyfloat(key, increment);
    }

    // 批量操作
    bool delPrimary(const std::string& primary) {
        std::string pattern = buildPattern(primary);
        auto keys = _redis->Keys(pattern);
        
        if (keys.empty()) {
            return false;
        }

        for (const auto& key : keys) {
            _redis->del(key);
        }
        return true;
    }

    std::vector<std::string> getSecondaryKeys(const std::string& primary) {
        std::string pattern = buildPattern(primary);
        auto keys = _redis->Keys(pattern);
        
        std::vector<std::string> secondaryKeys;
        for (const auto& key : keys) {
            secondaryKeys.push_back(extractSecondaryKey(key));
        }
        return secondaryKeys;
    }

    template<typename T>
    std::unordered_map<std::string, T> getAll(const std::string& primary) {
        std::string pattern = buildPattern(primary);
        auto keys = _redis->Keys(pattern);
        
        std::unordered_map<std::string, T> result;
        for (const auto& key : keys) {
            std::string secondary = extractSecondaryKey(key);
            auto value = _redis->get<T>(key);
            if (value) {
                result[secondary] = *value;
            }
        }
        return result;
    }

    template<typename T>
    std::unordered_map<std::string, T> getMultiple(const std::string& primary, 
                                                  const std::vector<std::string>& secondaries) {
        std::unordered_map<std::string, T> result;
        for (const auto& secondary : secondaries) {
            auto value = get<T>(primary, secondary);
            if (value) {
                result[secondary] = *value;
            }
        }
        return result;
    }

    template<typename T>
    bool setMultiple(const std::string& primary, 
                    const std::unordered_map<std::string, T>& keyValues) {
        bool allSuccess = true;
        for (const auto& [secondary, value] : keyValues) {
            if (!set(primary, secondary, value)) {
                allSuccess = false;
            }
        }
        return allSuccess;
    }

    // 统计功能
    long long count(const std::string& primary) {
        std::string pattern = buildPattern(primary);
        auto keys = _redis->Keys(pattern);
        return keys.size();
    }

    // 搜索功能（简单前缀匹配）
    std::vector<std::string> searchKeys(const std::string& primary, const std::string& prefix) {
        auto allKeys = getSecondaryKeys(primary);
        std::vector<std::string> result;
        
        for (const auto& key : allKeys) {
            if (key.find(prefix) == 0) {
                result.push_back(key);
            }
        }
        return result;
    }

    // 清理操作
    void flushall() {
        _redis->flushall();
    }

    bool flushNamespace() {
        std::string pattern = _namespace + ":*";
        auto keys = _redis->Keys(pattern);
        
        if (keys.empty()) {
            return false;
        }

        for (const auto& key : keys) {
            _redis->del(key);
        }
        return true;
    }

    // 批量删除
    bool batchDelete(const std::string& primary, const std::vector<std::string>& secondaries) {
        bool allSuccess = true;
        for (const auto& secondary : secondaries) {
            if (!del(primary, secondary)) {
                allSuccess = false;
            }
        }
        return allSuccess;
    }

    // 检查连接状态
    bool ping() {
        return _redis->ping();
    }

    // 获取信息
    std::string info() {
        return "KvMore实例 - 命名空间: " + _namespace;
    }
};